<template>
  <a-card title="用户查询" :bordered="false" class="condition-card">
    <div class="condition-row">
      <div class="condition-col flex align-center justify-between">
        <div class="input-box flex align-center">
          <span class="label mr-20">账号</span>
          <a-input allow-clear placeholder="请输入账号" v-model:value="conditionState.userName"></a-input>
        </div>
<!--        <div class="input-box flex align-center ml-20">-->
<!--          <span class="label mr-20">选择用户类型</span>-->
<!--          <a-select v-model:value="conditionState.userType" allow-clear placeholder="请选择用户类型" :options="UserTypes">-->
<!--          </a-select>-->
<!--        </div>-->
        <a-button class="ml-20" type="primary" :loading="searchLoading" @click="handleSearch">查询</a-button>
      </div>
    </div>
  </a-card>
  <a-card title="用户列表" :bordered="false" class="result-card mt-20">
    <template #extra>
      <a-button type="primary" @click="handlePopCreateModal">添加用户</a-button>
    </template>
    <a-table :columns="columns" :data-source="userList" :pagination="false" :scroll="{y: 'calc(100vh - 405px)'}">
      <template #bodyCell="{record, column}">
        <template v-if="column.dataIndex === 'userType'">
          <span v-if="record.userType !== UserTypesObj.bus.code">{{UserTypesObj[record.userType].label}}</span>
          <div class="tag primary-tag" v-else>{{UserTypesObj[record.userType].label}}</div>
        </template>
        <template v-if="column.dataIndex === 'option'">
          <a-button type="link" @click="handlePopEditModal(record)">
            <i class="iconfont icon-bianji"></i>
          </a-button>
          <a-popconfirm
              v-if="record.userType === UserTypesObj.bus.code"
              title="确定要重置密码吗?"
              ok-text="确定"
              cancel-text="取消"
              @confirm="handleResetPwd(record)">
            <a-tooltip title="重置密码">
              <a-button class="ml-12" type="link">
                <i class="iconfont icon-zhongzhimima"></i>
              </a-button>
            </a-tooltip>
          </a-popconfirm>
          <a-button class="ml-12" v-if="record.userType === UserTypesObj.bus.code" type="link" @click="handlePopEditRoleAuthModal(record)" v-authOperate="'operate-userRoleSetting'">用户角色设置</a-button>
<!--          <a-popconfirm-->
<!--              title="确定要删除吗?"-->
<!--              ok-text="确定"-->
<!--              cancel-text="取消"-->
<!--              @confirm="handleDelRecord(record)">-->
<!--            <a-button class="ml-12" type="link" danger>-->
<!--              <i class="iconfont icon-shanchu"></i>-->
<!--            </a-button>-->
<!--          </a-popconfirm>-->
        </template>
      </template>
    </a-table>
    <div class="pagination-content flex justify-end">
      <a-pagination v-model:current="conditionState.page" show-quick-jumper show-size-changer :show-total="total => `共 ${total} 条`" :total="total" v-model:pageSize="conditionState.size" @change="handlePageChange" />
    </div>
  </a-card>
  <a-modal :width="520" :mask-closable="false" :title="editMode ? '编辑用户信息' : '添加用户信息'" v-model:visible="modalVisible" :confirmLoading="saveLoading" @ok="handleSave">
    <a-form
        layout="vertical"
        :model="formState"
        :rules="rules"
        ref="userForm">
      <a-form-item
          label="账号"
          name="userName">
        <a-input v-model:value="formState.userName" placeholder="3-16位，只能包含数字、字母及下划线" :maxlength="16"></a-input>
      </a-form-item>
      <a-form-item
          v-if="!editMode"
          label="密码"
          name="password">
        <div class="flex align-center">
          <a-input v-model:value="formState.password" placeholder="8-20位，只能包含数字、字母、下划线及!@#$%&*" :maxlength="20"></a-input>
          <a-button class="ml-20" @click="handleRandomPwd">随机密码</a-button>
        </div>
      </a-form-item>
<!--      <a-form-item-->
<!--          label="用户类型"-->
<!--          name="userType">-->
<!--        <a-select v-model:value="formState.userType" allow-clear placeholder="请选择用户类型" :options="UserTypes">-->
<!--        </a-select>-->
<!--      </a-form-item>-->
      <a-form-item
          label="昵称"
          name="nickName">
        <a-input v-model:value="formState.nickName" placeholder="请输入昵称"></a-input>
      </a-form-item>
      <a-form-item
          label="所属组织"
          name="parentCode">
        <a-tree-select
            v-model:value="formState.departmentCode"
            show-search
            :field-names="{children:'child', label:'name', value:'code'}"
            placeholder="请选择"
            allow-clear
            tree-default-expand-all
            :tree-data="departmentList"
            treeNodeLabelProp="name"
            tree-node-filter-prop="name"></a-tree-select>
      </a-form-item>
<!--      <a-form-item-->
<!--          label="性别"-->
<!--          name="sex">-->
<!--        <a-select v-model:value="formState.sex" :options="UserSex" placeholder="请选择性别"></a-select>-->
<!--      </a-form-item>-->
    </a-form>
  </a-modal>
  <a-modal :width="520" title="用户角色设置" v-model:visible="authModalVisible" :confirmLoading="authSaveLoading" @ok="handleSaveRoleAuth">
    <a-form
        layout="vertical">
      <a-form-item
          label="账号">
        <a-input disabled v-model:value="currentFormItem.userName" placeholder="请输入账号"></a-input>
      </a-form-item>
      <a-form-item
          label="角色">
        <a-select v-model:value="selectedRoleList" allow-clear mode="multiple" placeholder="请选择角色">
          <a-select-option v-for="role in roleList" :value="role.roleCode" :label="role.roleName">{{role.roleName}}</a-select-option>
        </a-select>
      </a-form-item>
    </a-form>
  </a-modal>
</template>

<script setup lang="ts">
import {nextTick, reactive, ref} from "vue";
import api from '../../api/users'
import deptApi from '../../api/departments'
import roleApi from '../../api/roles'
import {DepartmentItem, MenuItem, ResDto, RoleItem, UserItem} from '../../types/common'
import {UserTypes, UserTypesObj, UserSex} from '../../common/constants'
import {formatDateTime, uuid} from '../../common/utils'
import {message, notification} from "ant-design-vue";
import authApi from "../../api/auth";
const modalVisible = ref<boolean>(false)
const editMode = ref<boolean>(false)
const defFormState = {
  "id": "",
  "userName": "",
  "password": "",
  "userType": UserTypesObj.bus.code,
  "nickName": "",
  sex: undefined,
  "birthday": "",
  "departmentCode": "",
  "email": "",
}
const departmentList = ref<DepartmentItem[]>([])
const getDepartmentTreeData = async () => {
  departmentList.value = []
  try {
    const res = await deptApi.getList()
    if (res.content && res.content.length) {
      departmentList.value = res.content
    }
  } catch(e: any) {
  }
}
const currentFormItem = ref()
const formState = ref({...defFormState})
const userForm = ref()
const rules = {
  userName: [
    { required: true, trigger: 'blur', message: '请输入账号' },
    { pattern: /^[a-zA-Z0-9_]{3,16}$/gi, trigger: 'blur', message: '3-16位，只能包含数字、字母及下划线' },
  ],
  password: [
    { required: true, trigger: 'blur', message: '请输入密码' },
    { pattern: /^[a-zA-Z0-9_!@#$%&*]{8,20}$/gi, trigger: 'blur', message: '8-20位，只能包含数字、字母、下划线及!@#$%&*' },
  ],
  // userType: [
  //   { required: true, trigger: 'change', message: '请选择用户类型' },
  // ],
}
const searchLoading = ref<boolean>(false)
const saveLoading = ref<boolean>(false)
const conditionState = reactive({
  userName: '',
  userType: UserTypesObj.bus.code,
  page: 1,
  size: 10,
})
const total = ref<number>(0)
const userList = ref<UserItem[]>([])
const columns = [
  {
    dataIndex: 'userName',
    key: 'userName',
    title: '账号',
  },{
    dataIndex: 'nickName',
    key: 'nickName',
    title: '昵称',
  },{
    dataIndex: 'createdDate',
    key: 'createdDate',
    title: '创建时间',
  },{
    dataIndex: 'lastLoginTime',
    key: 'lastLoginTime',
    title: '最后登录',
  },{
    dataIndex: 'option',
    key: 'option',
    title: '操作',
  },
]
const getPageData = async () => {
  searchLoading.value = true
  userList.value = []
  try {
    const res = await api.getList({
      userName: conditionState.userName || '',
      userType: conditionState.userType || '',
      page: conditionState.page - 1,
      size: conditionState.size,
    })
    searchLoading.value = false
    if (res.content) {
      total.value = res.content.total || 0
      if (res.content.content && res.content.content.length) {
        res.content.content.forEach((user: UserItem) => {
          user.createdDate = formatDateTime(new Date(user.createdDate))
          user.lastLoginTime = user.lastLoginTime ? formatDateTime(new Date(user.lastLoginTime)) : ''
        })
        userList.value = res.content.content
      }
    }
  } catch(e: any) {
    searchLoading.value = false
  }
}
const roleList = ref<RoleItem[]>([])
const getRoleList = async () => {
  roleList.value = []
  try {
    const res = await roleApi.getList({
      roleName: '',
      page: 0,
      size: 999,
    })
    if (res.content) {
      if (res.content.content && res.content.content.length) {
        roleList.value = res.content.content
      }
    }
  } catch(e: any) {
  }
}
const handleSearch = () => {
  conditionState.page = 1
  total.value = 0
  getPageData()
}
const handlePageChange = (page: number, pageSize: number) => {
  if (pageSize !== conditionState.size) {
    conditionState.page = 1
  }
  getPageData()
}
handleSearch()
getDepartmentTreeData()
getRoleList()
const handleSave = async () => {
  try {
    await userForm.value.validateFields()
    console.log('formState', formState.value)
    saveLoading.value = true
    let res
    if (!editMode.value) {
      res = await api.create(formState.value)
    } else {
      res = await api.edit(formState.value)
    }
    saveLoading.value = false
    if (res.success) {
      if (!editMode.value) {
        message.success('用户添加成功')
        notification.success({
          message: '密码提示',
          description: (formState.value.nickName || formState.value.userName)+' 用户的密码为：'+formState.value.password,
          placement: 'bottomRight',
          duration: null,
        })
        handleSearch()
      } else {
        message.success('用户修改成功')
        Object.assign(currentFormItem.value, formState.value)
      }
      modalVisible.value = false
    } else {
      let msg = '操作失败'
      if (res.errors && res.errors[0] && res.errors[0].message) {
        msg = res.errors[0].message
      }
      message.error(msg)
    }
  }catch(e){
    saveLoading.value = false
    if (e.errors && e.errors[0] && e.errors[0].message) {
      message.error(e.errors[0].message)
    }
    console.log(e)
  }
}
const handleRandomPwd = () => {
  formState.value.password = uuid(12, 0, '0123456789_!@#$%&*ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')
}
const handlePopCreateModal = () => {
  formState.value = {...defFormState}
  handleRandomPwd()
  editMode.value = false;
  modalVisible.value = true
  nextTick(() => {
    userForm.value.clearValidate()
  })
}
const handlePopEditModal = (item: any) => {
  currentFormItem.value = item
  Object.assign(formState.value, item)
  editMode.value = true;
  modalVisible.value = true
  nextTick(() => {
    userForm.value.clearValidate()
  })
}
const handleDelRecord = async (item: any) => {
  try {
    const res = await api.del(item.id)
    if (res.success) {
      message.success('删除成功')
      handleSearch()
    } else {
      let msg = '操作失败'
      if (res.errors && res.errors[0] && res.errors[0].message) {
        msg = res.errors[0].message
      }
      message.error(msg)
    }
  } catch (e) {
    if (e.errors && e.errors[0] && e.errors[0].message) {
      message.error(e.errors[0].message)
    }
    console.log(e)
  }
}

const handleResetPwd = (record: UserItem) => {
  const data = JSON.parse(JSON.stringify(record))
  data.password = uuid(12, 0, '0123456789_!@#$%&*ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz')
  api.edit(data).then((res: ResDto) => {
    if (res.success) {
      notification.success({
        message: '密码修改成功',
        description: (data.nickName || data.userName)+' 用户的新密码为：'+data.password,
        placement: 'bottomRight',
        duration: null,
      })
    } else {
      let msg = '操作失败'
      if (res.errors && res.errors[0] && res.errors[0].message) {
        msg = res.errors[0].message
      }
      message.error(msg)
    }
  }).catch((e: any) => {
    if (e.errors && e.errors[0] && e.errors[0].message) {
      message.error(e.errors[0].message)
    }
  })
}
const authModalVisible = ref(false)
const authSaveLoading = ref(false)
const selectedRoleList = ref<String[]>([])
const getUserRoleList = (user: UserItem) => {
  selectedRoleList.value = []
  authApi.getUserRoleAuth(user.userName).then((res: ResDto) => {
    if (res.content && res.content.length) {
      selectedRoleList.value = res.content.filter((role: RoleItem) => role.flag === '1').map((role: RoleItem) => role.roleCode)
    }
  })
}
const handlePopEditRoleAuthModal = (user: UserItem) => {
  currentFormItem.value = user
  getUserRoleList(user)
  authModalVisible.value = true
}
const handleSaveRoleAuth = () => {
  authSaveLoading.value = true
  authApi.setUserRoleAuth(currentFormItem.value.userName, selectedRoleList.value.map((roleCode: string) => {return {roleCode}})).then((res: ResDto) => {
    authSaveLoading.value = false;
    if (res.success) {
      message.success('用户角色权限设置成功')
      authModalVisible.value = false;
    } else {
      let msg = '用户角色权限设置失败'
      if (res.errors && res.errors[0] && res.errors[0].message) {
        msg = res.errors[0].message
      }
      message.error(msg)
    }
  }).catch((e: any) => {
    authSaveLoading.value = false
    if (e.errors && e.errors[0] && e.errors[0].message) {
      message.error(e.errors[0].message)
    }
    console.log(e)
  })
}
</script>

<style scoped lang="less">
  .condition-col{
    .ant-input{
      min-width: 300px;
    }
    .ant-select{
      min-width: 160px;
    }
    .ant-input-affix-wrapper{
      width: 200px;
    }
  }
  .ant-btn-link{
    padding: 0;
  }
</style>
